package com.kuangjia.student_ems.controller;

import com.kuangjia.student_ems.dto.SalaryRecordDTO;
import com.kuangjia.student_ems.dto.SalarySchemeDTO;
import com.kuangjia.student_ems.service.SalaryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.EasyExcel;
import jakarta.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.io.IOException;

import java.util.List;
import java.util.Map;
import com.kuangjia.student_ems.dto.SalaryExportVO;
import org.springframework.security.core.Authentication;

@RestController
@RequestMapping("/salary")
public class SalaryController {

    private static final Logger logger = LoggerFactory.getLogger(SalaryController.class);

    @Autowired
    private SalaryService salaryService;

    // 薪资方案管理
    @GetMapping("/schemes")
    @PreAuthorize("hasRole('HR_ADMIN')")
    public ResponseEntity<List<SalarySchemeDTO>> getAllSalarySchemes() {
        try {
            return ResponseEntity.ok(salaryService.getAllSalarySchemes());
        } catch (Exception e) {
            logger.error("获取薪资方案列表失败", e);
            throw e;
        }
    }

    @GetMapping("/schemes/{id}")
    @PreAuthorize("hasRole('HR_ADMIN')")
    public ResponseEntity<SalarySchemeDTO> getSalarySchemeById(@PathVariable Long id) {
        try {
            return ResponseEntity.ok(salaryService.getSalarySchemeById(id));
        } catch (Exception e) {
            logger.error("获取薪资方案失败，ID: {}", id, e);
            throw e;
        }
    }

    @PostMapping("/schemes")
    @PreAuthorize("hasRole('HR_ADMIN')")
    public ResponseEntity<SalarySchemeDTO> createSalaryScheme(@RequestBody SalarySchemeDTO schemeDTO) {
        try {
            return ResponseEntity.ok(salaryService.createSalaryScheme(schemeDTO));
        } catch (Exception e) {
            logger.error("创建薪资方案失败", e);
            throw e;
        }
    }

    @PutMapping("/schemes/{id}")
    @PreAuthorize("hasRole('HR_ADMIN')")
    public ResponseEntity<SalarySchemeDTO> updateSalaryScheme(@PathVariable Long id, @RequestBody SalarySchemeDTO schemeDTO) {
        try {
            return ResponseEntity.ok(salaryService.updateSalaryScheme(id, schemeDTO));
        } catch (Exception e) {
            logger.error("更新薪资方案失败，ID: {}", id, e);
            throw e;
        }
    }

    @DeleteMapping("/schemes/{id}")
    @PreAuthorize("hasRole('HR_ADMIN')")
    public ResponseEntity<Void> deleteSalaryScheme(@PathVariable Long id) {
        try {
            salaryService.deleteSalaryScheme(id);
            return ResponseEntity.ok().build();
        } catch (Exception e) {
            logger.error("删除薪资方案失败，ID: {}", id, e);
            throw e;
        }
    }

    // 薪资记录管理
    @GetMapping("/records")
    @PreAuthorize("hasRole('HR_ADMIN') or hasRole('DEPARTMENT_MANAGER') or principal.id != null")
    public ResponseEntity<?> getSalaryRecords(
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize,
            @RequestParam(required = false) Integer year,
            @RequestParam(required = false) Integer month,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) Long userId,
            Authentication authentication) {
        try {
            Page<SalaryRecordDTO> page = new Page<>(pageNum, pageSize);
            boolean isHR = authentication.getAuthorities().stream().anyMatch(a -> a.getAuthority().contains("HR") || a.getAuthority().contains("DEPARTMENT_MANAGER"));
            Long realUserId = null;
            if (!isHR) {
                // 普通员工只能查自己的，强制用当前登录用户id
                Object principal = authentication.getPrincipal();
                Long currentUserId = null;
                if (principal instanceof com.kuangjia.student_ems.security.UserDetailsServiceImpl.CustomUserDetails customUser) {
                    currentUserId = customUser.getId();
                } else if (principal instanceof com.kuangjia.student_ems.entity.User user) {
                    currentUserId = user.getId();
                }
                realUserId = currentUserId;
            } else {
                // 管理员/部门经理可查全部或指定userId
                realUserId = userId;
            }
            return ResponseEntity.ok(salaryService.getSalaryRecords(page, year, month, status, realUserId));
        } catch (Exception e) {
            logger.error("获取薪资记录失败", e);
            return ResponseEntity.status(500).body("获取薪资记录失败: " + e.getMessage());
        }
    }

    @GetMapping("/records/{id}")
    @PreAuthorize("hasRole('HR_ADMIN') or hasRole('DEPARTMENT_MANAGER') or @salarySecurity.hasRecordPermission(#id, authentication)")
    public ResponseEntity<SalaryRecordDTO> getSalaryRecordById(@PathVariable Long id, Authentication authentication) {
        try {
            SalaryRecordDTO dto = salaryService.getSalaryRecordById(id, authentication);
            if (dto == null) {
                return ResponseEntity.status(403).build();
            }
            return ResponseEntity.ok(dto);
        } catch (Exception e) {
            logger.error("获取薪资记录失败，ID: {}", id, e);
            throw e;
        }
    }

    // ======= 薪资核算相关接口已注释/移除 =======
    // @PostMapping("/calculate")
    // public ResponseEntity<Map<String, Object>> calculateSalary(
    //         @RequestParam Integer year,
    //         @RequestParam Integer month) {
    //     try {
    //         Map<String, Object> result = salaryService.calculateSalary(year, month);
    //         return ResponseEntity.ok(result);
    //     } catch (Exception e) {
    //         logger.error("薪资核算失败，年份: {}, 月份: {}", year, month, e);
    //         throw e;
    //     }
    // }
    //
    // @PostMapping("/calculate/{userId}")
    // public ResponseEntity<SalaryRecordDTO> calculateUserSalary(
    //         @PathVariable Long userId,
    //         @RequestParam Integer year,
    //         @RequestParam Integer month) {
    //     try {
    //         return ResponseEntity.ok(salaryService.calculateUserSalary(userId, year, month));
    //     } catch (Exception e) {
    //         logger.error("员工薪资核算失败，用户ID: {}, 年份: {}, 月份: {}", userId, year, month, e);
    //         throw e;
    //     }
    // }
    //
    // @PostMapping("/batch-confirm")
    // public ResponseEntity<Map<String, Object>> batchConfirmSalary(
    //         @RequestParam Integer year,
    //         @RequestParam Integer month) {
    //     try {
    //         Map<String, Object> result = salaryService.batchConfirmSalary(year, month);
    //         return ResponseEntity.ok(result);
    //     } catch (Exception e) {
    //         logger.error("批量确认薪资失败，年份: {}, 月份: {}", year, month, e);
    //         throw e;
    //     }
    // }
    //
    // 批量发放工资
    @PostMapping("/batch-pay")
    @PreAuthorize("hasRole('HR_ADMIN')")
    public ResponseEntity<Map<String, Object>> batchPaySalary(@RequestParam Integer year, @RequestParam Integer month) {
        try {
            Map<String, Object> result = salaryService.batchPaySalary(year, month);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            logger.error("批量发放薪资失败，年份: {}, 月份: {}", year, month, e);
            return ResponseEntity.status(500).body(Map.of("error", "批量发放薪资失败: " + e.getMessage()));
        }
    }
    // ======= END =======

    // 薪资确认和发放
    @PostMapping("/confirm/{id}")
    public ResponseEntity<?> confirmSalary(@PathVariable Long id, Authentication authentication) {
        try {
            Long userId = null;
            Object principal = authentication.getPrincipal();
            if (principal instanceof com.kuangjia.student_ems.security.UserDetailsServiceImpl.CustomUserDetails customUser) {
                userId = customUser.getId();
            } else if (principal instanceof com.kuangjia.student_ems.entity.User user) {
                userId = user.getId();
            }
            salaryService.confirmSalaryByUser(id, userId);
            return ResponseEntity.ok().build();
        } catch (Exception e) {
            logger.error("确认薪资失败", e);
            return ResponseEntity.status(500).body("确认薪资失败: " + e.getMessage());
        }
    }

    @PutMapping("/records/{id}/pay")
    public ResponseEntity<SalaryRecordDTO> paySalary(@PathVariable Long id) {
        try {
            return ResponseEntity.ok(salaryService.paySalary(id));
        } catch (Exception e) {
            logger.error("发放薪资失败，ID: {}", id, e);
            throw e;
        }
    }

    // 薪资统计
    @GetMapping("/statistics")
    public ResponseEntity<Map<String, Object>> getSalaryStatistics(
            @RequestParam(required = false) Integer year,
            @RequestParam(required = false) Integer month) {
        try {
            return ResponseEntity.ok(salaryService.getSalaryStatistics(year, month));
        } catch (Exception e) {
            logger.error("获取薪资统计失败", e);
            throw e;
        }
    }

    // 批量生成本月薪资记录
    @PostMapping("/batch-generate")
    @PreAuthorize("hasRole('HR_ADMIN')")
    public ResponseEntity<Map<String, Object>> batchGenerateSalaryRecords(@RequestParam Integer year, @RequestParam Integer month) {
        try {
            Map<String, Object> result = salaryService.batchGenerateSalaryRecords(year, month);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            logger.error("批量生成薪资记录失败", e);
            throw e;
        }
    }

    // 一键删除本月薪资记录
    @DeleteMapping("/batch-delete")
    @PreAuthorize("hasRole('HR_ADMIN')")
    public ResponseEntity<Map<String, Object>> batchDeleteSalaryRecords(@RequestParam Integer year, @RequestParam Integer month) {
        try {
            Map<String, Object> result = salaryService.batchDeleteSalaryRecords(year, month);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            logger.error("批量删除薪资记录失败", e);
            throw e;
        }
    }

    @GetMapping("/export")
    @PreAuthorize("hasRole('HR_ADMIN')")
    public void exportSalaryRecords(
            @RequestParam(required = false) Integer year,
            @RequestParam(required = false) Integer month,
            HttpServletResponse response) throws IOException {
        try {
            List<SalaryRecordDTO> records = salaryService.getSalaryRecords(
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<SalaryRecordDTO>(1, Integer.MAX_VALUE),
                year, month, null, null
            ).getRecords();
            List<SalaryExportVO> exportList = records.stream().map(dto -> {
                SalaryExportVO vo = new SalaryExportVO();
                vo.setUserName(dto.getUserName());
                vo.setUserDepartment(dto.getUserDepartment());
                vo.setUserPosition(dto.getUserPosition());
                vo.setYear(dto.getYear());
                vo.setMonth(dto.getMonth());
                vo.setSchemeName(dto.getSchemeName());
                vo.setBaseSalary(dto.getBaseSalary());
                vo.setAttendanceDeduction(dto.getAttendanceDeduction());
                vo.setSocialSecurity(dto.getSocialSecurity());
                vo.setHousingFund(dto.getHousingFund());
                vo.setTax(dto.getTax());
                vo.setTotalSalary(dto.getTotalSalary());
                vo.setNetSalary(dto.getNetSalary());
                vo.setStatus(dto.getStatus());
                vo.setRemark(dto.getRemark());
                return vo;
            }).toList();
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("薪资记录.xlsx", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);
            EasyExcel.write(response.getOutputStream(), SalaryExportVO.class)
                    .sheet("薪资记录")
                    .doWrite(exportList);
        } catch (Exception e) {
            logger.error("导出薪资记录失败", e);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"error\":\"导出薪资记录失败: " + e.getMessage() + "\"}");
        }
    }
} 